import 'dart:async';
import 'dart:convert';
import 'dart:ui';
import 'package:crypto/crypto.dart';
import 'package:encrypt/encrypt.dart';
import 'package:flutter/services.dart';
import 'package:flutter/widgets.dart';
import 'package:get/get.dart';
import 'package:pointycastle/asymmetric/api.dart';
import 'package:hixing_app/const/color_res.dart';
import 'package:hixing_app/extensions/date_ext.dart';
import 'package:hixing_app/extensions/str_ext.dart';
// import 'package:hixing_app/views/wallet/enum/wallet_enum.dart';

class Utils {
  Utils._();

  static List splitList(List list, int len) {
    if (len == 0) {
      return [list];
    }
    List result = [];
    int index = 1;
    while (true) {
      if (index * len < list.length) {
        List temp = list.skip((index - 1) * len).take(len).toList();
        result.add(temp);
        index++;
        continue;
      }
      List temp = list.skip((index - 1) * len).toList();
      result.add(temp);
      break;
    }
    return result;
  }

  static Map<String, dynamic> stringToJson(String str) {
    return jsonDecode(str);
  }

  static List<dynamic> stringToList(String str) {
    return jsonDecode(str);
  }

  static String jsonToString(Map map) {
    return jsonEncode(map);
  }

  static String regTime(dynamic time) {
    if (time.runtimeType == int) {
      return DateTime.fromMillisecondsSinceEpoch((time as int)).regular;
    } else if (time.runtimeType == String) {
      return DateTime.parse((time as String).safety).toLocal().regular;
    } else {
      return "";
    }
  }

  static String regTimeYMDhm(dynamic time) {
    if (time.runtimeType == int) {
      return DateTime.fromMillisecondsSinceEpoch((time as int)).ymdhm;
    } else if (time.runtimeType == String) {
      return DateTime.parse((time as String).safety).toLocal().ymdhm;
    } else {
      return "";
    }
  }

  static String regTimeYMD(dynamic time) {
    if (time.runtimeType == int) {
      return DateTime.fromMillisecondsSinceEpoch((time as int)).ymd;
    } else if (time.runtimeType == String) {
      return DateTime.parse((time as String).safety).toLocal().ymd;
    } else {
      return "";
    }
  }

  static void tailSelection(TextEditingController ctrl) {
    ctrl.selection =
        TextSelection.fromPosition(TextPosition(offset: ctrl.text.length));
  }

  /// 函数防抖
  ///  防抖: 操作停止多久之后触发操作，比如输入框输入，调用接口，在输入框停止输入多久之后才调用操作
  /// [func]: 要执行的方法
  /// [delay]: 要迟延的时长
  static void Function()? debounce(
    Function func, {
    Duration delay = const Duration(milliseconds: 800),
  }) {
    Timer? timer;
    target() {
      if (timer?.isActive ?? false) {
        timer?.cancel();
      }
      timer = Timer(delay, () {
        func.call();
      });
    }

    return target;
  }

  static String encryptRASPwd({required String pubKey, required String pwd}) {
    //     .loadString("assets/key/pubkey.pem");
    var _keyObj = "-----BEGIN PUBLIC KEY-----\n"
        "$pubKey\n"
        "-----END PUBLIC KEY-----";
    //创建公钥对象
    RSAPublicKey publicKey = RSAKeyParser().parse(_keyObj) as RSAPublicKey;
    final encrypter = Encrypter(RSA(publicKey: publicKey));
    final String encryptPwd = encrypter.encrypt(generateMD5(pwd)).base64;
    return encryptPwd;
  }

  static dynamic Function(String) textDebounce(
    Function(String) func, {
    Duration delay = const Duration(milliseconds: 800),
  }) {
    Timer? timer;
    target(val) {
      if (timer?.isActive ?? false) {
        timer?.cancel();
      }
      timer = Timer(delay, () {
        func.call(val);
      });
    }

    return target;
  }

  static dynamic Function(double) doubleDebounce(
    Function(double) func, {
    Duration delay = const Duration(milliseconds: 800),
  }) {
    Timer? timer;
    target(val) {
      if (timer?.isActive ?? false) {
        timer?.cancel();
      }
      timer = Timer(delay, () {
        func.call(val);
      });
    }

    return target;
  }

  static String generateMD5(String data) {
    Uint8List content = const Utf8Encoder().convert(data);
    Digest digest = md5.convert(content);
    return digest.toString().toUpperCase();
  }

  /// 函数节流
  /// 节流: 多少时间内执行一次，相当于 抢单的时候，前端限制，每三秒只能发送一次下单接口
  /// [func]: 要执行的方法
  static Future? Function()? throttle(
    Future Function()? func,
  ) {
    if (func == null) {
      return func;
    }
    bool enable = true;
    target() {
      if (enable == true) {
        enable = false;
        func().then((_) {
          enable = true;
        });
      }
    }

    return target;
  }

  // static Color getWalletColor({WalletChannel? type, int id = 0}) {
  //   final List<Color> _colors = [
  //     ColorRes.walletBBg2,
  //     ColorRes.walletABg2,
  //     ColorRes.walletCBg2,
  //   ];
  //   final Map<WalletChannel, Color> _walletColorMap = {
  //     WalletChannel.walletB: _colors[0],
  //     WalletChannel.walletA: _colors[1],
  //     WalletChannel.walletC: _colors[2],
  //   };
  //   if (type != null) {
  //     return _walletColorMap[type]!;
  //   } else {
  //     return _colors[id];
  //   }
  // }
  //
  // static WalletChannel getWalletTypeFromId({required int id}) {
  //   if (id == 0) {
  //     return WalletChannel.walletB;
  //   } else if (id == 1) {
  //     return WalletChannel.walletA;
  //   } else {
  //     return WalletChannel.walletC;
  //   }
  // }

  static Uint8List consolidateHttpClientResponseBytes(List<int> data) {
    // response.contentLength is not trustworthy when GZIP is involved
    // or other cases where an intermediate transformer has been applied
    // to the stream.
    final List<List<int>> chunks = <List<int>>[];
    int contentLength = 0;
    chunks.add(data);
    contentLength += data.length;
    final Uint8List bytes = Uint8List(contentLength);
    int offset = 0;
    for (List<int> chunk in chunks) {
      bytes.setRange(offset, offset + chunk.length, chunk);
      offset += chunk.length;
    }
    return bytes;
  }
}
